package com.snail.starter.cloud.tracing;

import cn.hutool.extra.servlet.ServletUtil;
import com.snail.starter.utils.id.ObjectId;
import com.snail.starter.commons.enums.HeaderEnums;
import com.snail.starter.commons.threadlocal.UserContext;
import com.snail.starter.commons.threadlocal.UserContextUtils;
import lombok.extern.slf4j.Slf4j;
import org.slf4j.MDC;
import org.springframework.core.Ordered;
import org.springframework.web.filter.OncePerRequestFilter;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

/**
 * @author: snail framework
 * @Date: 2023/2/20 上午9:44
 * @Version: 1.0.0
 */
@Slf4j
public class TracingSimpleFilter extends OncePerRequestFilter implements Ordered {
    @Override
    public int getOrder() {
        return Ordered.HIGHEST_PRECEDENCE;
    }

    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
        try {
            String trace = request.getHeader(HeaderEnums.TRACE.getKey());
            UserContext userContext = UserContextUtils.get();
            if (null == trace || "".equals(trace)) {
                userContext.setTraceId(ObjectId.nextId());
                userContext.setSpanId(ObjectId.nextId());
            } else {
                userContext.setTraceId(ObjectId.nextId());
                userContext.setSpanId(trace);
            }
            UserContextUtils.set(userContext);
            MDC.put("traceId", userContext.getTraceId());
            MDC.put("spanId", userContext.getSpanId());
            MDC.put("ip", ServletUtil.getClientIP(request));
            filterChain.doFilter(request, response);
        } finally {
            MDC.clear();
            UserContextUtils.clear();
        }
    }
}
